import { _decorator, Component, Label, Node, Tween, tween, v3, Vec3 } from 'cc';
import { Dish } from '../common/Dish';
const { ccclass, property } = _decorator;

@ccclass('Line')
export class Line extends Component {
    
    @property(Node)
    mask: Node = null!

    @property(Label)
    tip: Label = null!

    @property(Node)
    zone: Node = null!

    type: number = 1

    full: number = 6

    need: number = 0

    touchable: boolean = true

    /**
     * 初始化
     * @param type 类型
     */
    init(type: number = 1, need: number) {
        this.type = type
        this.changeState(need)
        this.changeFull()
    }

    /** 设置最大餐盘数 */
    changeFull() {
        switch(this.type) {
            case 1:
            case 2:
            case 3:
            case 5:
            case 6:
                this.full = 6
                break
            case 4:
                this.full = 12
                break
            case 7:
                this.full = 11
                break
        }
    }

    /**
     * 改变流水线状态
     * @param need 所需客人
     */
    changeState(need: number) {
        this.need = need < 0 ? 0 : need
        this.unlock()
    }

    /** 解锁 */
    unlock() {
        this.mask.active = (this.need > 0)
        this.tip.string = this.type == 1 ? '再服务 ' + this.need + '名 客人解锁' : '再服务\n' + this.need + '名\n客人解锁'
    }

    /**
     * 根据顺位获取位置
     * @param index 顺位
     * @returns 位置
     */
    getDishPos(index: number): Vec3 {
        let pos: Vec3 = null
        switch(this.type) {
            case 1:
                pos = v3(275 - index * 110, -3, 0)
                break
            case 2:
                if (index <= 1) {
                    pos = v3(-33 + index * 108, -162, 0)
                } else if (1 < index && index <= 4) {
                    pos = v3(75, -54 + (index - 2) * 108, 0)
                } else if (4 < index) {
                    pos = v3(-33 - (index - 5) * 108, 162, 0)
                }
                break
            case 3:
                if (index <= 1) {
                    pos = v3(33 - index * 108, -162, 0)
                } else if (1 < index && index <= 4) {
                    pos = v3(-75, -54 + (index - 2) * 108, 0)
                } else if (4 < index) {
                    pos = v3(33 + (index - 5) * 108, 162, 0)
                }
                break
            case 4:
                if (index <= 0) {
                    pos = v3(253 - index * 168, 145, 0)
                } else if (0 < index && index <= 2) {
                    pos = v3(253, 145 - index * 146, 0)
                } else if (2 < index && index <= 3) {
                    pos = v3(253 - (index - 2) * 168, -147, 0)
                } else if (3 < index && index <= 5) {
                    pos = v3(85, -147 + (index - 3) * 146, 0)
                } else if (5 < index && index <= 6) {
                    pos = v3(85 - (index - 5) * 168, 145, 0)
                } else if (6 < index && index <= 8) {
                    pos = v3(-83, 145 - (index - 6) * 146, 0)
                } else if (8 < index && index <= 9) {
                    pos = v3(-83 - (index - 8) * 168, -147, 0)
                } else if (9 < index && index <= 11) {
                    pos = v3(-251, -147 + (index - 9) * 146, 0)
                } else if (11 < index) {
                    pos = v3(-251 - (index - 11) * 168, 145, 0)
                }
                break
            case 5:
                if (index < 0) {
                    pos = v3(26 + index * 128, -320, 0)
                } else if (0 <= index && index < 5) {
                    pos = v3(26, -320 + index * 128, 0)
                } else {
                    pos = v3(26 - (index - 5) * 128, 320, 0)
                }
                break
            case 6:
                if (index < 0) {
                    pos = v3(-26 - index * 128, -320, 0)
                } else if (0 <= index && index < 5) {
                    pos = v3(-26, -320 + index * 128, 0)
                } else {
                    pos = v3(-26 + (index - 5) * 128, 320, 0)
                }
                break
            case 7:
                if (index <= 4) {
                    pos = v3(85, -300 + index * 135, 0)
                } else if (4 < index && index < 4.5) {
                    pos = v3(85 - (index - 4) * 30, 240 + (index - 4) * 160, 0)
                } else if (index == 4.5) {
                    pos = v3(70, 320, 0)
                } else if (4.5 < index && index < 5) {
                    pos = v3(70 - (index - 4.5) * 140, 320 + (index - 4.5) * 60, 0)
                } else if (index == 5) {
                    pos = v3(0, 350, 0)
                } else if (5 < index && index < 5.5) {
                    pos = v3(0 - (index - 5) * 140, 350 - (index - 5) * 60, 0)
                } else if (index == 5.5) {
                    pos = v3(-70, 320, 0)
                } else if (5.5 < index && index < 6) {
                    pos = v3(-70 - (index - 5.5) * 30, 320 - (index - 5.5) * 160, 0)
                } else if (6 <= index) {
                    pos = v3(-85, 240 - (index - 6) * 135, 0)
                }
                pos.add3f(0, 410, 0)
                break
        }
        return pos
    }

    changeDishState() {
        let children = this.zone.children
        for (let i = 0; i < children.length; i++) {
            let dn1 = children[i]
            let dish1 = dn1.getComponent(Dish)
            dish1.touchState(true)
            for (let j = 0; j < children.length; j++) {
                let dn2 = children[j]
                let dish2 = dn2.getComponent(Dish)
                if (Math.abs(dish2.index - dish1.index) < 1 && dish2.floor > dish1.floor) {
                    dish1.touchState(false)
                }
            }
        }
    }

    moveDishes(index: number, step: number = 0.1, interval: number = 1) {
        let children = this.zone.children
        for (let i = 0; i < children.length; i++) {
            let dn: Node = children[i]
            let dish: Dish = dn.getComponent(Dish)
            if (dish.index > index) {
                dish.index -= interval
                tween(dn)
                    .to(step / 2, { position: this.getDishPos(dish.index + interval / 2) })
                    .to(step / 2, { position: this.getDishPos(dish.index) })
                    .start()
            }
        }
    }

    smoothMoveDishes(type: 'in' | 'out' = 'in', then?: () => void) {
        this.touchable = false
        let check: Dish = null
        let children = this.zone.children
        for (let i = 0; i < children.length; i++) {
            let dn: Node = children[i]
            let dish: Dish = dn.getComponent(Dish)
            check = (check == null ? dish : (type == 'in' ? (dish.index < check.index ? dish : check) : ((dish.index > check.index ? dish : check))))
        }
        if (!check) {
            return
        }
        let delay: number = type == 'in' ? 0.1 : 0.02
        let t =  tween(this)
            .call(() => {
                if (check.index <= 0) {
                    Tween.stopAllByTarget(this)
                    this.touchable = true
                    if (then) {
                        then()
                    }
                }
            })
            .delay(delay - 0.001)
            .call(() => {
                this.moveDishes(-1, delay, 0.5)
            })
        tween(this).repeatForever(t).start()
    }

    getAllDishesByFloor(): Dish[][] {
        let dishes: Dish[][] = []
        let ds = this.zone.children
        for (let i = 0; i < ds.length; i++) {
            let dn: Node = ds[i]
            let dish: Dish = dn.getComponent(Dish)
            let floor: number = dish.floor
            let df = dishes[floor]
            if (!df) {
                df = []
            }
            df.push(dish)
            dishes[floor] = df
        }
        return dishes
    }

    getDishesByFloor(floor: number): Dish[] {
        let ds = this.getAllDishesByFloor()
        return ds[floor] ? ds[floor] : []
    }
}


